package com.jyy.prefabricated.controller;

import cn.hutool.http.HttpUtil;
import com.baidubce.util.JsonUtils;
import com.jyy.prefabricated.common.AjaxResult;
import com.jyy.prefabricated.service.BosService;
import com.jyy.prefabricated.utils.QrCodeUtil;
import com.jyy.prefabricated.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 文件上传
 * @version 1.0.0
 * @author: zjj
 */
@Slf4j
@RequestMapping("/api")
@RestController
@CrossOrigin
public class UploadFileController {

    @Value("${bos.bucketName}")
    private String bucketName; //所属区域名

    @Value("${polyv.userId}")
    private String userId; //保利威userId

    @Value("${polyv.secretKey}")
    private String secretKey; //保利威secretKey

    @Value("${polyv.writetoken}")
    private String writetoken; //保利威writetoken

    @Value("${tgm.ewmUrl}")
    private String ewmUrl;

    @Value("${tgm.ewmPath}")
    private String ewmPath;
    @Autowired
    private BosService bosService;

    @Autowired
    private UserUtils userUtils;

    /**
     * 上传文件
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/uploadFile")
    public AjaxResult uploadFile(@RequestParam(value = "file") MultipartFile file) throws IOException {
        log.debug("REST request to upload file to OSS ");
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        String objectName = UUID.randomUUID().toString().replace("-","") + substring;
        Map<String,Object> result = new HashMap<>();
        String url = bosService.putObject(file,objectName);
        result.put("url",url);
        return AjaxResult.success(result);
    }
    @GetMapping("/extensionCode/{mobile}")
    public AjaxResult extensionCode(@PathVariable String mobile ) throws IOException {
        log.debug("REST request to upload file to OSS ");
        File qrFile = QrCodeUtil.createQrCode(ewmUrl+mobile, ewmPath, mobile);
        String objectName = UUID.randomUUID().toString().replace("-","") + mobile;
        Map<String,Object> result = new HashMap<>();
        String url = bosService.putFile(qrFile,objectName+".jpg");
        result.put("url",url);
        return AjaxResult.success(result);
    }
    /**
     * 删除文件
     * @param path
     * @return
     */
    @DeleteMapping("/deleteFile/{path}")
    public AjaxResult uploadFile(@PathVariable String path) {
        String objectKey = path.substring(path.lastIndexOf('/') +1);
        bosService.deleteObject(bucketName, objectKey);
        return AjaxResult.success();
    }

    /**
     * 获取保利威签名
     * @return
     */
    @GetMapping("/polyv")
    public AjaxResult polyv(){
        Map<String,Object> result = new HashMap<>();
        Long ptime = new Date().getTime();
        String sign = DigestUtils.md5Hex(secretKey + ptime);
        String hash = DigestUtils.md5Hex(ptime + writetoken);
        result.put("userid",userId);
        result.put("ptime",ptime);
        result.put("sign",sign);
        result.put("hash",hash);
        return AjaxResult.success(result);
    }

    /**
     * 获取保利威ts签名
     * @param vid
     * @return
     */
    @GetMapping("/polyv/ts-sign")
    public AjaxResult polyvTsSign(String vid){
        Map<String,Object> result = new HashMap<>();
        Long ts = System.currentTimeMillis();
        String sign = DigestUtils.md5Hex("secretKey" + secretKey + "vid" + vid + "ts" + ts);
        result.put("ts",ts);
        result.put("sign",sign);
        return AjaxResult.success(result);
    }

    /**
     * 保利威安全认证
     * @param request
     * @param vid
     * @return
     */
    @ResponseBody
    @RequestMapping("/polyv/playerSafe")
    public AjaxResult playerSafe(HttpServletRequest request, String vid) {
        String userId = this.userId;       // 保利威点播账号的userId
        String secretkey = this.secretKey;     // 保利威点播账号的secretkey
        String videoId = vid;  // 视频vid
        long ts = System.currentTimeMillis();      // 时间戳
        String viewerIp = getClientIp(request);  // 观众ip
        //String viewerId = userUtils.getCurrentUsername();      // 观众id
        //String viewerName = userUtils.getCurrentUsername();  // 观众昵称, 若值为中文需要urlencode('张三')
        String viewerId = "123";   // 观众id
        String viewerName = "123";
        String extraParams = "jianyeyun";  // 自定义扩展参数
        boolean disposable = false; // true 表示 token 仅一次有效。false 则表示在有效期内可以多次验证。默认为 false。

        /* 将参数 userId、secretkey、videoId、ts、viewerIp、viewerIp、viewerId、viewerName、extraParams按照ASCKII升序 key + value + key + value ... +value 拼接
         */
        String concated = "extraParams" + extraParams + "ts" + ts + "userId" + userId + "videoId" + videoId + "viewerId" + viewerId + "viewerIp" + viewerIp + "viewerName" + viewerName;
        // 首尾加上secretkey值
        String plain = secretkey + concated + secretkey;
        // 取大写MD5，可自行选择md5库  垃圾保利威，文档写的是大写，要改成小写
        String sign = DigestUtils.md5Hex(plain).toUpperCase();


        //String sign = DigestUtils.md5Hex(plain).toUpperCase();

        // 然后将下列参数用post请求  https://hls.videocc.net/service/v1/token 获取 token
        String url = "https://hls.videocc.net/service/v1/token";

        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("videoId", videoId);
        params.put("ts", String.valueOf(ts));
        params.put("viewerIp", viewerIp);
        params.put("viewerName", viewerName);
        params.put("extraParams", extraParams);
        params.put("viewerId", viewerId);
        params.put("sign", sign);
        // 可自行选择http客户端
        String response = HttpUtil.post(url, params);

        try {
            //解析json
            TokenResponse tokenResponse = JsonUtils.fromJsonString(response, TokenResponse.class);
            // 响应代码，200为成功，403为ts过期或签名错误，400为参数错误（例如缺少 userId 或 videoId）
            if (tokenResponse.getCode() == 200) {
                Map data = (Map) tokenResponse.getData();
                String playsafe = data.get("token").toString();
                Map result = new HashMap();
                result.put("playsafe", playsafe);
                result.put("ts", ts);

                /*String[] arr =new String[3];
                arr[0] = this.secretKey;
                arr[1] = videoId;
                arr[2] = String.valueOf(ts);
                Arrays.sort(arr);
                String signMsg = "";

                for(int i = 0; i < arr.length; i++) {
                    signMsg += arr[i];
                }*/
                String signMsg = this.secretKey + videoId + ts;
                String signAfter = DigestUtils.md5Hex(signMsg);
                log.info("签名前 {}", signMsg);
                log.info("签名后 {}", signAfter);

                result.put("sign", signAfter);
                return AjaxResult.success(result);
            } else {
                log.info("token response {}", tokenResponse);
                return AjaxResult.success("获取token失败", tokenResponse);
            }
        } catch (Exception e) {
            log.error("get play safe error ", e);
        }
        return null;
    }

    static class TokenResponse {
        int code;
        String status;
        String message;
        Object data;

        public int getCode() {
            return code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public Object getData() {
            return data;
        }

        public void setData(Object data) {
            this.data = data;
        }
    }
    public String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }



    @RequestMapping(value = "/polyv/auth", method = RequestMethod.GET, produces= "application/javascript")
    public String playerAuth(String vid, Long t , String code, String callback, HttpServletResponse res) {
        log.info("auth param , vid {}, code {} , callback {}， t {}", vid, code, callback, t);
        String username = userUtils.getCurrentUsernameByCode(code);
        if(username == null) {
            username = "18130089467";
        }
        String secretKey = this.secretKey;
        String fontSize = "40", fontColor = "0xFFE900", speed = "200",
                filter = "on", setting = "3", alpha = "1", filterAlpha = "1",
                filterColor = "0x3914AF", blurX = "2", blurY = "2", tweenTime = "1",
                interval = "5", lifeTime = "3", strength = "4", show = "on", msg = "Errormessage!";
        int status = 1;
        if (t == null) {
            t = System.currentTimeMillis();
        }
        String codeString = code == null? "" : code;
        // md5签名，自行选择md5库
        String plain = "vid=" + vid + "&secretkey=" + secretKey + "&username=" + username + "&code=" + codeString + "&status=" + status + "&t=" + t +
                "&msg=" + msg + "&fontSize=" + fontSize + "&fontColor=" + fontColor + "&speed=" + speed + "&filter=" + filter + "&setting=" + setting +
                "&alpha=" + alpha + "&filterAlpha=" + filterAlpha + "&filterColor=" + filterColor + "&blurX=" + blurX + "&blurY=" + blurY +
                "&interval=" + interval + "&lifeTime=" + lifeTime + "&tweenTime=" + tweenTime + "&strength=" + strength + "&show=" + show;
       //String plain = "vid=" + vid + "&secretkey=" + secretKey + "&username=" + username + "&code=" + code + "&status=" + status + "&t=" + t;

        log.info("拼接前的字符串 {}" , plain);

        String sign = DigestUtils.md5Hex(plain);

        log.info("签名数据 {}", sign);

        Map<String, Object> resultMap = new LinkedHashMap<>();
        resultMap.put("username", username);
        resultMap.put("status", status);
        resultMap.put("sign", sign);
        resultMap.put("msg", msg);
        resultMap.put("fontSize", fontSize);
        resultMap.put("fontColor", fontColor);
        resultMap.put("speed", speed);
        resultMap.put("filter", filter);
        resultMap.put("setting", setting);
        resultMap.put("alpha", alpha);
        resultMap.put("filterAlpha", filterAlpha);
        resultMap.put("filterColor", filterColor);
        resultMap.put("blurX", blurX);
        resultMap.put("blurY", blurY);
        resultMap.put("tweenTime", tweenTime);
        resultMap.put("interval", interval);
        resultMap.put("lifeTime", lifeTime);
        resultMap.put("strength", strength);
        resultMap.put("show", show);

        res.setHeader("Content-Type","application/javascript");
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Credentials","true"); //是否支持cookie跨域
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control,JSESSIONID,Content-disposition,access-control-allow-origin,content-type,x-requested-with,Content-Type,Access-Control-Allow-Headers,Content-Length,Accept,Authorization,X-Requested-With");

        // json序列化，可自行选择json序列化库
        String resultJson = "";
        try {
            resultJson = JsonUtils.toJsonString(resultMap);
        } catch (Exception e) {
            log.error("get poly auth error", e);
        }
        if (callback != null && !"".equals(callback)) {
            return callback + "(" + resultJson + ")";
        } else {
            return resultJson;
        }
    }


    /*public static void main(String[] args) {
        String[] arr =new String[3];
        arr[0] = "Tsjp1iGIeD";
        arr[1] = "313188177cf2e7d1afd7b44e6548aac7_3";
        arr[2] = String.valueOf(1617791970229L);
        Arrays.sort(arr);
        String signMsg = "";

        for(int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
            signMsg += arr[i];
        }
        String signAfter = DigestUtils.md5Hex(signMsg);
        System.out.println(signAfter);
    }*/

    public static void main(String[] args) {
        String plain = "vid=313188177cf2e7d1afd7b44e6548aac7_3&secretkey=Tsjp1iGIeD&username=18130089467&code=Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MTc4NDIzNTIsInN1YiI6IjE4MTMwMDg5NDY3IiwiaWF0IjoxNjE3Nzk5MTUyODkwfQ.jLAWUhV2d4b3tDJjjsR0rgYDnxtbZFI_pIVBf-wlUcIPT6eGu0FejvOjf3xcBDnsIo5kwqRsMkxdooxXQM0k0g&status=1&t=1617799229332&msg=Errormessage!&fontSize=40&fontColor=0xFFE900&speed=200&filter=on&setting=3&alpha=1&filterAlpha=1&filterColor=0x3914AF&blurX=2&blurY=2&interval=5&lifeTime=3&tweenTime=1&strength=4&show=on";
        String sign = DigestUtils.md5Hex(plain);
        System.out.println(sign);
    }

}
